`define AXI_TOP_INTERFACE(name) io_memAXI_0_``name
module SimTop(
    input                               clock,
    input                               reset,

    input  [63:0]                       io_logCtrl_log_begin,
    input  [63:0]                       io_logCtrl_log_end,
    input  [63:0]                       io_logCtrl_log_level,
    input                               io_perfInfo_clean,
    input                               io_perfInfo_dump,

    output                              io_uart_out_valid,
    output [7:0]                        io_uart_out_ch,
    output                              io_uart_in_valid,
    input  [7:0]                        io_uart_in_ch,

    input                               `AXI_TOP_INTERFACE(aw_ready),
    output                              `AXI_TOP_INTERFACE(aw_valid),
    output [63:0]                       `AXI_TOP_INTERFACE(aw_bits_addr),
    output [2:0]                        `AXI_TOP_INTERFACE(aw_bits_prot),
    output [4:0]                        `AXI_TOP_INTERFACE(aw_bits_id),
    output                              `AXI_TOP_INTERFACE(aw_bits_user),
    output [7:0]                        `AXI_TOP_INTERFACE(aw_bits_len),
    output [2:0]                        `AXI_TOP_INTERFACE(aw_bits_size),
    output [1:0]                        `AXI_TOP_INTERFACE(aw_bits_burst),
    output                              `AXI_TOP_INTERFACE(aw_bits_lock),
    output [3:0]                        `AXI_TOP_INTERFACE(aw_bits_cache),
    output [3:0]                        `AXI_TOP_INTERFACE(aw_bits_qos),
    
    input                               `AXI_TOP_INTERFACE(w_ready),
    output                              `AXI_TOP_INTERFACE(w_valid),
    output [63:0]                       `AXI_TOP_INTERFACE(w_bits_data)         [3:0],
    output [7:0]                        `AXI_TOP_INTERFACE(w_bits_strb),
    output                              `AXI_TOP_INTERFACE(w_bits_last),
    
    output                              `AXI_TOP_INTERFACE(b_ready),
    input                               `AXI_TOP_INTERFACE(b_valid),
    input  [1:0]                        `AXI_TOP_INTERFACE(b_bits_resp),
    input  [3:0]                        `AXI_TOP_INTERFACE(b_bits_id),
    input                               `AXI_TOP_INTERFACE(b_bits_user),

    input                               `AXI_TOP_INTERFACE(ar_ready),
    output                              `AXI_TOP_INTERFACE(ar_valid),
    output [63:0]                       `AXI_TOP_INTERFACE(ar_bits_addr),
    output [2:0]                        `AXI_TOP_INTERFACE(ar_bits_prot),
    output [3:0]                        `AXI_TOP_INTERFACE(ar_bits_id),
    output                              `AXI_TOP_INTERFACE(ar_bits_user),
    output [7:0]                        `AXI_TOP_INTERFACE(ar_bits_len),
    output [2:0]                        `AXI_TOP_INTERFACE(ar_bits_size),
    output [1:0]                        `AXI_TOP_INTERFACE(ar_bits_burst),
    output                              `AXI_TOP_INTERFACE(ar_bits_lock),
    output [3:0]                        `AXI_TOP_INTERFACE(ar_bits_cache),
    output [3:0]                        `AXI_TOP_INTERFACE(ar_bits_qos),
    
    output                              `AXI_TOP_INTERFACE(r_ready),
    input                               `AXI_TOP_INTERFACE(r_valid),
    input  [1:0]                        `AXI_TOP_INTERFACE(r_bits_resp),
    input  [63:0]                       `AXI_TOP_INTERFACE(r_bits_data)         [3:0],
    input                               `AXI_TOP_INTERFACE(r_bits_last),
    input  [3:0]                        `AXI_TOP_INTERFACE(r_bits_id),
    input                               `AXI_TOP_INTERFACE(r_bits_user)
);

    wire aw_ready;
    wire aw_valid;
    wire [63:0] aw_addr;
    wire [2:0] aw_prot;
    wire [3:0] aw_id;
    wire aw_user;
    wire [7:0] aw_len;
    wire [2:0] aw_size;
    wire [1:0] aw_burst;
    wire aw_lock;
    wire [3:0] aw_cache;
    wire [3:0] aw_qos;
    wire [3:0] aw_region;

    wire w_ready;
    wire w_valid;
    wire [63:0] w_data;
    wire [7:0] w_strb;
    wire w_last;
    wire w_user;
    
    wire b_ready;
    wire b_valid;
    wire [1:0] b_resp;
    wire [3:0] b_id;
    wire b_user;

    wire ar_ready;
    wire ar_valid;
    wire [63:0] ar_addr;
    wire [2:0] ar_prot;
    wire [3:0] ar_id;
    wire ar_user;
    wire [7:0] ar_len;
    wire [2:0] ar_size;
    wire [1:0] ar_burst;
    wire ar_lock;
    wire [3:0] ar_cache;
    wire [3:0] ar_qos;
    wire [3:0] ar_region;
    
    wire r_ready;
    wire r_valid;
    wire [1:0] r_resp;
    wire [63:0] r_data;
    wire r_last;
    wire [3:0] r_id;
    wire r_user;

    assign ar_ready                                 = `AXI_TOP_INTERFACE(ar_ready);
    assign `AXI_TOP_INTERFACE(ar_valid)             = ar_valid;
    assign `AXI_TOP_INTERFACE(ar_bits_addr)         = ar_addr;
    assign `AXI_TOP_INTERFACE(ar_bits_prot)         = ar_prot;
    assign `AXI_TOP_INTERFACE(ar_bits_id)           = ar_id;
    assign `AXI_TOP_INTERFACE(ar_bits_user)         = ar_user;
    assign `AXI_TOP_INTERFACE(ar_bits_len)          = ar_len;
    assign `AXI_TOP_INTERFACE(ar_bits_size)         = ar_size;
    assign `AXI_TOP_INTERFACE(ar_bits_burst)        = ar_burst;
    assign `AXI_TOP_INTERFACE(ar_bits_lock)         = ar_lock;
    assign `AXI_TOP_INTERFACE(ar_bits_cache)        = ar_cache;
    assign `AXI_TOP_INTERFACE(ar_bits_qos)          = ar_qos;
    
    assign `AXI_TOP_INTERFACE(r_ready)              = r_ready;
    assign r_valid                                  = `AXI_TOP_INTERFACE(r_valid);
    assign r_resp                                   = `AXI_TOP_INTERFACE(r_bits_resp);
    assign r_data                                   = `AXI_TOP_INTERFACE(r_bits_data)[0];
    assign r_last                                   = `AXI_TOP_INTERFACE(r_bits_last);
    assign r_id                                     = `AXI_TOP_INTERFACE(r_bits_id);
    assign r_user                                   = `AXI_TOP_INTERFACE(r_bits_user);

    assign aw_ready                                 = `AXI_TOP_INTERFACE(aw_ready);
    assign `AXI_TOP_INTERFACE(aw_valid)             = aw_valid;
    assign `AXI_TOP_INTERFACE(aw_bits_addr)         = aw_addr;
    assign `AXI_TOP_INTERFACE(aw_bits_prot)         = aw_prot;
    assign `AXI_TOP_INTERFACE(aw_bits_id)           = aw_id;
    assign `AXI_TOP_INTERFACE(aw_bits_user)         = aw_user;
    assign `AXI_TOP_INTERFACE(aw_bits_len)          = aw_len;
    assign `AXI_TOP_INTERFACE(aw_bits_size)         = aw_size;
    assign `AXI_TOP_INTERFACE(aw_bits_burst)        = aw_burst;
    assign `AXI_TOP_INTERFACE(aw_bits_lock)         = aw_lock;
    assign `AXI_TOP_INTERFACE(aw_bits_cache)        = aw_cache;
    assign `AXI_TOP_INTERFACE(aw_bits_qos)          = aw_qos;
    
    assign w_ready                                  = `AXI_TOP_INTERFACE(w_ready);
    assign `AXI_TOP_INTERFACE(w_valid)              = w_valid;
    assign `AXI_TOP_INTERFACE(w_bits_data)[0]       = w_data;
    assign `AXI_TOP_INTERFACE(w_bits_last)          = w_last;
    assign `AXI_TOP_INTERFACE(w_bits_strb)          = w_strb;

    assign `AXI_TOP_INTERFACE(b_ready)              = b_ready ;
    assign b_valid                                  = `AXI_TOP_INTERFACE(b_valid);
    assign b_resp                                   = `AXI_TOP_INTERFACE(b_bits_resp);
    assign b_id                                     = `AXI_TOP_INTERFACE(b_bits_id);
    assign b_user                                   = `AXI_TOP_INTERFACE(b_bits_user);

    wire flush;
    wire data_r_valid;
    wire data_w_valid;
    wire [63:0] data_r_data;
    wire [31:0] inst_r_data;
    wire inst_r_valid;
    wire inst_r_ena;
    wire [63:0] inst_r_addr;
    wire [63:0] data_w_addr;
    wire [63:0] data_w_data;
    wire data_w_ena;
    wire data_r_ena;
    wire [63:0] data_r_addr;
    wire [7:0] mem_mask;

  mycpu CPU(
      .clock(clock), 
      .reset(reset), 
      .data_r_valid(data_r_valid), 
      .data_w_valid(data_w_valid), 
      .data_r_data(data_r_data), 
      .inst_r_data(inst_r_data), 
      .inst_r_valid(inst_r_valid),
      .inst_r_ena(inst_r_ena), 
      .inst_r_addr(inst_r_addr), 
      .data_w_addr(data_w_addr), 
      .data_w_data(data_w_data), 
      .data_w_ena(data_w_ena), 
      .data_r_ena(data_r_ena), 
      .data_r_addr(data_r_addr), 
      .mem_mask(mem_mask),
      .flush(flush),
      .print_ena(io_uart_out_valid),
      .print_ch(io_uart_out_ch));

    axi4_crtl AXI(
      .ACLK(clock), 
      .ARESETn(reset),
      .flush(flush), 
      .inst_r_ena(inst_r_ena), 
      .inst_addr(inst_r_addr), 
      .inst_r(inst_r_data),
      .data_r_ena(data_r_ena), 
      .data_w_ena(data_w_ena), 
      .data_w(data_w_data), 
      .data_addr(data_r_addr), 
      .data_w_addr(data_w_addr),
      .data_w_mask(mem_mask),
      .wlast_i(1'b1), 
      .data_r(data_r_data), 
      .ARID(ar_id),
      .ARADDR(ar_addr), 
      .ARLEN(ar_len),
      .ARSIZE(ar_size),
      .ARBURST(ar_burst),
      .ARLOCK(ar_lock),
      .ARCACHE(ar_cache),
      .ARPROT(ar_prot),
      .ARQOS(ar_qos),
      .ARREGION(ar_region),
      .ARVALID(ar_valid), 
      .ARREADY(ar_ready), 
      .RID(r_id), 
      .RDATA(r_data), 
      .RVALID(r_valid), 
      .RREADY(r_ready), 
      .RLAST(r_last),
      .RRESP(r_resp),
      .AWID(aw_id), 
      .AWADDR(aw_addr), 
      .AWLEN(aw_len),
      .AWSIZE(aw_size),
      .AWBURST(aw_burst),
      .AWLOCK(aw_lock),
      .AWCACHE(aw_cache),
      .AWPROT(aw_prot),
      .AWQOS(aw_qos),
      .AWREGION(aw_region),
      .AWVALID(aw_valid), 
      .AWREADY(aw_ready), 
      .WDATA(w_data), 
      .WSTRB(w_strb), 
      .WVALID(w_valid), 
      .WREADY(w_ready),
      .WLAST(w_last), 
      .BID(b_id), 
      .BVALID(b_valid), 
      .BREADY(b_ready),
      .BRESP(b_resp),
      .data_r_valid(data_r_valid),
      .data_w_valid(data_w_valid),
      .inst_r_valid(inst_r_valid));
endmodule